import Foundation
import CryptoKit
import SwiftUI
import CommonCrypto



struct QiniuUtils {
    
    // 七牛云上传所需的参数
    static var accessKey : String = ""
    static var secretKey : String = ""
    static var bucket : String = ""
    static var host : String = ""
    
    // 生成七牛UploadToken, 需要自己设置token有效时间
    func generateUploadToken() -> String {
        // 1.确定上传策略
        let jsonReturnBody = """
    {
        "key": "$(key)",
        "hash": "$(etag)",
        "size": "$(fsize)",
        "mimeType": "$(mimeType)"             
    }
    """
        
        var jsonDict: [String: Any] = [:]
        jsonDict["scope"] = QiniuUtils.bucket
        jsonDict["deadline"] = Int(Date().timeIntervalSince1970) + 3600
        jsonDict["returnBody"] =  jsonReturnBody
        
        let jsonData = toJsonData(dict: jsonDict)
        let json = toJson(dict: jsonDict)
        showLog("上传json串：\(json)")
        if jsonData == nil {
            showLog("解析数据失败")
            return ""
        }
        
        // 3.对json序列化后的上传策略进行URL安全的Base64编码,得到如下encoded
        let encoded = URLSafeBase64Encode(data: jsonData!)
        
        // 4.用SecretKey对编码后的上传策略进行HMAC-SHA1加密，并且做URL安全的Base64编码,得到如下的encoded_signed
        let encoded_signed = HMACSHA1(key: QiniuUtils.secretKey, text: encoded)
        
        // 5.将 AccessKey、encode_signed 和 encoded 用 “:” 连接起来,得到如下的UploadToken
        let uploadToken = "\(QiniuUtils.accessKey):\(encoded_signed):\(encoded)"
        
        return uploadToken
    }
    
    //删除加密url
    func deletegetEencodedUrl(fileName : String) ->String {
        let entryUrl = "\(QiniuUtils.bucket):\(fileName)"
        let encoded = URLSafeBase64Encode(data: entryUrl.data(using: String.Encoding.utf8)!)
        return encoded
    }
    
    //删除token
    func deleteToken(fileName : String) -> String{
        let eencodedUrl = deletegetEencodedUrl(fileName: fileName)
        let path = "/delete/\(eencodedUrl)"
        let encoded_signed = HMACSHA1(key: QiniuUtils.secretKey, text: "\(path)\n")
        let delToken = "\(QiniuUtils.accessKey):\(encoded_signed)"
        return "QBox \(delToken)"
    }
    
    func getKey(url : String)->String{
        let key = url.replacingOccurrences(of: "http://\(QiniuUtils.host)/", with: "")
        return key
    }
    
    // URL安全的Base64编码
    func URLSafeBase64Encode(data: Data) -> String {
        var base64 = data.base64EncodedString()
        base64 = base64.replacingOccurrences(of: "+", with: "-")
        base64 = base64.replacingOccurrences(of: "/", with: "_")
        return base64
    }
    
    // HMAC-SHA1加密，并且做URL安全的Base64编码
    func HMACSHA1(key: String, text: String) -> String {
        let cKey = key.cString(using: .utf8)!
        let cData = text.cString(using: .utf8)!
        var cHMAC = [CUnsignedChar](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
        CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cKey, strlen(cKey), cData, strlen(cData), &cHMAC)
        let HMAC = Data(bytes: cHMAC, count: Int(CC_SHA1_DIGEST_LENGTH))
        let hash = URLSafeBase64Encode(data: HMAC)
        return hash
    }
    
    func getHttpBody(fileData: Data, key: String) -> (Data,String){
        let keyName = "imprint/\(key)"
        let token = generateUploadToken()
        let boundary = "Boundary-\(UUID().uuidString)"
        
        var body = Data()
        // 添加 token 字段
        body.append("--\(boundary)\r\n".data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"token\"\r\n\r\n".data(using: .utf8)!)
        body.append("\(token)\r\n".data(using: .utf8)!)
        
        // 添加 key 字段
        body.append("--\(boundary)\r\n".data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"key\"\r\n\r\n".data(using: .utf8)!)
        body.append("\(keyName)\r\n".data(using: .utf8)!)
        
        // 添加文件字段
        body.append("--\(boundary)\r\n".data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(keyName)\"\r\n".data(using: .utf8)!)
        body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: .utf8)!)
        
        body.append(fileData)
        body.append("\r\n".data(using: .utf8)!)
        
        // 添加结束边界
        body.append("--\(boundary)--\r\n".data(using: .utf8)!)
        return (body, boundary)
    }
    
    
    static func getCompressUrl(_ isVideo: Bool, _ realUrl: String, _ width: Int, _ height: Int) -> String? {
            if (isVideo) {
                return getVideoCover(realUrl, width, height, 200)
            }
            return getThumbnail(realUrl, width, height, 200)
        }
    
    /**
     * 根据宽度，压缩等比例高度的图片
     */
    static func getThumbnail(_ url: String, _ width: Int, _ height: Int, _ newWidth: Int) -> String? {
        if (width == 0 || height == 0) {
            return QiniuUtils.getUrl(url, newWidth)
        }
        let newHeight = Int((Float(newWidth) / Float(width) * Float(height)).rounded())
        
        if (newHeight >= 10000) {
            //目前只接受最大高度，所以需要在缩小宽度，避免高度过大
            return getThumbnail(url, width, height, newWidth / 2)
        }
        return QiniuUtils.getUrl(url, newWidth, newHeight)
    }
    
    
    /**
     * 根据宽度，压缩等比例高度的图片
     */
    static func getVideoCover(_ url: String, _ width: Int, _ height: Int, _ newWidth: Int) -> String? {
        if (width == 0 || height == 0) {
            return getVideoCover(url, newWidth)
        }
        let newHeight = Int((Float(newWidth) / Float(width) * Float(height)).rounded())

        return getVideoCover(
            url,
            newWidth,
            newHeight
        )
    }

    
    static func getVideoCover(_ url: String?, _ width: Int, _ height: Int) -> String? {
        guard let url = url else {
            return nil
        }
        
        let host = QiniuUtils.host // 请确保 HOST 常量在 Swift 中已正确定义
        let httpPrefix = "http://\(host)"
        let httpsPrefix = "https://\(host)"
        
        guard url.hasPrefix(httpPrefix) || url.hasPrefix(httpsPrefix) else {
            return url
        }
        
        let parameters = String(format: "?vframe/jpg/offset/0/w/%d/h/%d", width, height)
        return url + parameters
    }
    
    /**
     * 根据宽度，压缩等比例高度的图片
     */
    static func getVideoCover(_ url: String?, _ width: Int) -> String? {
        guard let url = url else {
            return nil
        }
        
        let host = QiniuUtils.host // 请确保 HOST 常量在 Swift 中已正确定义
        let httpPrefix = "http://\(host)"
        let httpsPrefix = "https://\(host)"
        
        guard url.hasPrefix(httpPrefix) || url.hasPrefix(httpsPrefix) else {
            return url
        }
        
        let parameters = String(format: "?vframe/jpg/offset/0/w/%d/", width)
        return url + parameters
    }
    
    
    static func getUrl(_ url: String?, _ width: Int, _ height: Int) -> String? {
        guard let url = url else {
            return nil
        }
        
        let host = QiniuUtils.host // 请确保 HOST 常量在 Swift 中已正确定义
        let httpPrefix = "http://\(host)"
        let httpsPrefix = "https://\(host)"
        
        guard url.hasPrefix(httpPrefix) || url.hasPrefix(httpsPrefix) else {
            return url
        }
        
        let parameters = String(format: "?imageView2/1/w/%d/h/%d", width, height)
        return url + parameters
    }
    
    
    static func getUrl(_ url: String?, _ width: Int) -> String? {
        guard let url = url else {
            return nil
        }
        
        let host = QiniuUtils.host // 请确保 HOST 常量在 Swift 中已正确定义
        let httpPrefix = "http://\(host)"
        let httpsPrefix = "https://\(host)"
        
        guard url.hasPrefix(httpPrefix) || url.hasPrefix(httpsPrefix) else {
            return url
        }
        
        let parameters = String(format: "?imageView2/1/w/%d/h/%d", width)
        return url + parameters
    }
}
